<template>
  <div class="commonQueryTable" :style="commpStyle">
    <div ref="canvasDiv" class="container" v-loading.fullscreen.lock="loading" :element-loading-text="loadingTex"
         fullscreen
         element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.2)">
      <!--回调按钮提示框-->
      <el-button type="text" @click="open" style="display: none"></el-button>
      <div v-if="tableTitle.visible" class="tableName">
        <i :class="tableTitle.icon" @click="expandOrFoldMain()"
           style="cursor:pointer;"> </i><span>&nbsp;&nbsp;{{ tableTitle.name }}</span>
      </div>
      <div style="width: 100% ; height: 100%" v-if="tableVisible">
        <CommonAvueQuery
          ref="commonAvueQuery"
          v-if="queryBar.visible"
          class="avueQuery"
          :split-line="queryBar.splitLine"
          :query-data="queryBar.queryData"
          :query-option="queryBar.queryOption"
          :menu-span="queryBar.menuSpan"
          @queryList="queryList"
        >
        </CommonAvueQuery>
        <div>
          <CommonTable
            ref="commonTable"
            class="configTable"
            :toolbar="newToolBar"
            :tableHeader="newTableHeader"
            :tableHeaderRender="newTableHeaderRender"
            :expand-render="expandRender"
            :tableList="newTableList"
            :pageBar="pageBar"
            :lazy="lazy"
            :tree-props="treeProps"
            :table-height="tableHeight"
            :table-max-height="tableMaxHeight"
            :isMultiple="isMultiple"
            :isRadio="isRadio"
            :expand="expand"
            :row-key="rowKey"
            :expand-row-keys="expandRowKeys"
            :default-expand-all="defaultExpandAll"
            :column-max-num="columnMaxNum"
            :theme="theme"
            @pageChange="pageChange"
            @cellClick="cellClick"
            @rowClick="rowClick"
            @loadMethod="loadMethod"
            @expandChange="expandChange"
            @tableSelected="tableSelected"
          >
          </CommonTable>
        </div>
      </div>
    </div>
  </div>
</template>
<script>

import CommonConfigForm from "./commonConfigForm.vue";
import CommonAvueQuery from './commonAvueQuery';
import CommonTable from './commonTable';

import BaseComp from './baseComp'

export default {
  name: 'newCommonQueryTable',
  components: {
    CommonAvueQuery, CommonTable, CommonConfigForm
  },
  extends: BaseComp,
  model: {
    prop: "value",
    event: "queryTableListChange",
  },
  props: {
    //v-model绑定数据
    value: {
      type: [Array, String, Object]
    },
    //表格数据
    tableList: {
      type: Array,
      default: () => [],
    },
    requstParams: { //表格请求数据参数
      type: Object,
      default: () => {
      }
    },
    params: {
      type: Object,
      default: () => {
      }
    },
    isMultiple: { //是否多选框
      type: Boolean,
      default: true,
    },
    isRadio: { //是否单选框
      type: Boolean,
      default: false,
    },
    expand: { //是否展开行
      type: Boolean,
      default: false,
    },
    defaultExpandAll: { //列是否展开
      type: Boolean,
      default: false,
    },
    lazy: { //是否懒加载
      type: Boolean,
      default: false
    },
    treeProps: { //树形表格树形props配置
      type: Object,
      default: () => {
        return {
          children: 'children',
          hasChildren: 'leaf'
        }
      }
    },
    tableHeight: { //表格高度
      type: [String, Number],
    },
    tableMaxHeight: { //表格最大高度
      type: [String, Number],
    },
    columnMaxNum: {
      type: Number
    },

    //**********************************************************************************

    rowKey: { //行标识
      type: String,
      default: 'id'
    },

    //表格标题
    tableTitle: {
      type: Object,
      default: {
        visible: false,
        name: '',
        icon: 'el-icon-arrow-down'
      }
    },
    //查询栏
    queryBar: {
      type: Object,
      default: () => {
        return {
          visible: false,
          splitLine: true,
          queryOption: {
            column: [],
          },
          queryData: {},
          menuSpan: 2
        }
      }
    },
    // 工具栏
    toolbar: {
      //列分页
      columnPage: {
        visible: true,
        width: 'auto',
        height: 'auto'
      },
      //自定义组件区域
      custom: {
        row: 1,
        col: 24,
        render: [
          {
            rowNum: 1,
            colNum: 1,
            component: '',
            width: '',
            height: '',
            config: {}
          }
        ]
      }
    },
    //表头数据
    tableHeader: {
      type: Array,
      default: () => [],
    },
    //表格组件渲染配置
    tableHeaderRender: {
      type: Array,
      default: () => [{rowNum: 1, colNum: 1, component: '', config: {}}]
    },
    //行分页栏
    pageBar: {
      type: Object,
      default: () => {
        return {
          visible: true,
          pageSize: 10,
          pageNum: 1,
          total: 0
        }
      }
    },
    //展开行渲染配置
    expandRender: {
      type: Object,
    },
  },
  watch: {
    tableHeader: {
      handler(val) {
        this.newTableHeader = val
      },
      immediate: true,
      deep: true
    },
    tableList: {
      handler(val) {
        this.newTableList = val
      },
      immediate: true,
      deep: true
    },
    toolbar: {
      handler(val) {
        this.newToolBar = val;
      },
      immediate: true,
      deep: true
    },
    tableHeaderRender: {
      handler(val) {
        this.newTableHeaderRender = val;
      },
      immediate: true,
      deep: true
    },
    value: {
      handler(nowRow) {
        if (nowRow) {
          let rows = [];
          if (typeof nowRow == "object") {
            rows.push(nowRow);
          } else {
            rows = nowRow
          }
          this.$nextTick(() => {
            this.executeEvent('upRows', this.path, rows, this);
            for (let row of rows) {
              if (!this.isEmptyObject(row)) {
                let row_ = this.loopFindTableData(this.newTableList, row);
                if (!row_) {
                  this.newTableList.push(row);
                } else {
                  row_ = row;
                }
                this.$refs.commonTable.$refs.multipleTable.setCurrentRow(row);
              }
            }
          })
        }
      },
      immediate: true,
      deep: true
    },
    requstParams: {
      handler(val) {
        this.newRequestParam = val;
        this.$nextTick(() => {
          this.getInit();
        })
      },
      immediate: true,
      deep: true
    }
  },
  data() {
    return {
      newTableHeader: this.tableHeader,
      newTableList: this.value,
      newToolBar: {},
      newTableHeaderRender: this.tableHeaderRender,
      newRequestParam: this.requstParams,
      multipleSelection: [], //表格选中项集合
      currentRow: {}, //当前点击行数据项
      tableVisible: true,// 是否显示表格主体
      expandRowKeys: [],//展开行,数组形式
      loading: false, //tabel加载
      loadingTex: "解析处理中",
      dataSize: 0,//上传文件的大小
      dataList: [],//websock返回数据处理
      treeNodeList: [],//树形结构展开存放列
    }
  },
  created() {
  },
  mounted() {
    this.loadTheme(this.$options.name);
    this.wsSubscribe(this);
    // this.getInit();
  },
  methods: {
    open(data) {
      if (data.code == 0) {
        this.$message.success(data.msg);
      } else {
        this.$message.error(data.msg);
      }
      this.dataList.push(data);
      if (this.dataList.length >= this.dataSize) {
        this.loading = false;
        this.getInit();
      }
    },
    /**
     * 递归查找表格数据中是否存在row1数据项
     * @param {表格数据内容} tableDatas
     * @param {传入数据内容} row[]
     */
    loopFindTableData(tableDatas, row) {
      let item = {};
      if (row) {
        for (let i = 0; i < tableDatas.length; i++) {
          if (tableDatas[i][this.rowKey] && row[this.rowKey] && tableDatas[i][this.rowKey] == row[this.rowKey]) {
            item = tableDatas[i];
            return item;
            break;
            //   return tableDatas[i];
          }
          let children = tableDatas[i][this.treeProps.children];
          if (children && children.length > 0) {
            this.loopFindTableData(children, row);
          }
          return item;
        }
        // for (const item of tableDatas) {
        //
        // }
      }
    }
    ,
    /**
     * 初始化定时器，进行轮询操作
     */
    initTimer(intervalTime) {
      this.timer = setInterval(() => {
        this.getInit();
      }, intervalTime);
    }
    ,

    /**
     * 初始化请求参数
     */
    getInitParam() {
      let objRequest = {}
      // 组装查询参数
      let instanceUForm = this.buildQueryObj(this.newRequestParam.initRequstForm);
      let objectEmpty = this.isObjectEmpty(this.queryBar.queryData);
      if (!objectEmpty) {
        instanceUForm = {...instanceUForm, ...this.queryBar.queryData};
      }
      this.remove$Field(instanceUForm);
      objRequest.objid = this.newRequestParam.objid;
      objRequest.objtypeid = this.newRequestParam.objtypeid;
      objRequest.formId = this.newRequestParam.formId;
      objRequest.partIndex = this.newRequestParam.partIndex;
      objRequest.instanceUForm = instanceUForm;
      //判断是否需要分页参数
      if (this.pageBar.visible) {
        objRequest.pageNum = this.pageBar.pageNum;
        objRequest.pageSize = this.pageBar.pageSize;
      }
      return objRequest;
    }
    ,
    /**
     * 判断对象属性是否为空
     * @param {需要判断的数据对象} obj
     */
    isObjectEmpty(obj) {
      return Object.keys(obj).length === 0;
    }
    ,

    /**
     * 调用ajax请求远程服务器，获取数据
     */
    executeAjax(method, url, params) {
      return this.$myAxios.request(method, url, params).then(res => {
        return res
      })
    }
    ,
    /**
     * 获取远程服务器数据，根据请求参数，条件过滤，获取参数值
     * data：外部传入参数值
     * inner： 组件内容调用，还是外部调用， true内部，false：外部
     */
    getInit(data) {
      let obj = this.getInitParam();
      if (data) {
        obj.instanceUForm = {...obj.instanceUForm, ...data};
      }
      this.init(this.newRequestParam.initMethod, this.newRequestParam.initUrl, obj)
    }
    ,


    /**
     * 初始化加载数据表格数据
     * @param method 请求方式 post/get
     * @param url 请求地址，远程服务器地址
     * @param requestForm 请求参数，json格式的请求参数
     * @returns {Promise<void>}
     */
    async init(method, url, requestForm) {
      try {
        // this.executeEvent('beforeRequest', this.path, requestForm);
        if (url && url != '' && method && method != '') {
          let resData = await this.executeAjax(method, url, requestForm)
          //返回自定义数据结构对象，其中结构至少包含{records:[], totle: 3}
          let dicFormatter = this.newRequestParam.dicFormatter;
          if (typeof dicFormatter != 'function') {
            dicFormatter = eval(dicFormatter);
          }
          if (resData.data) {
            let responseData = dicFormatter(resData.data);
            this.$set(this, 'newTableList', responseData.records ? responseData.records : []);
            this.pageBar.total = responseData.total;
            //      this.$refs.commonTable.$refs.multipleTable.toggleRowExpansion(resData.data.data.records[0], true)
            // this.executeEvent("requestEnd", this.path, resData.data, this);
          }
        }
      } catch (e) {
        console.log(e)
      }
    }
    ,

    /**
     * 通过insert添加表格数据内容，次方法为静态添加数据方式，不冲后端服务获取数据内容。
     * @param {添加表格数据内容} data
     */
    insert(data) {
      this.newTableList.push(data);
    }
    ,

    /**
     * 主动刷新表格数据内容，此方法参数中必须包含当前表格数据行的唯一建内容，需要通过唯一键内容查找行数据并进行刷新操作。
     * 且数据数据内容中的刷新项属性名必须和原有表格行数据中的属性名一致。
     * @param {需要刷新的表格数据内容} data
     */
    update(data) {
      let rowDataIndex = this.newTableList.findIndex(item => item[this.rowKey] == data[this.rowKey]);
      if (rowDataIndex >= 0) {
        for (let key in data) {
          if (data.hasOwnProperty(key)) {
            this.newTableList[rowDataIndex][key] = data[key];
          }
        }
      }
    }
    ,

    /**
     * 主动删除表格数据内容，此方法参数中必须包含当前表格数据行的唯一建内容，需要通过唯一键内容查找行数据并进行删除操作。
     * @param {需要删除的数据内容} data
     */
    delete(data) {
      let index = this.newTableList.findIndex(item => item[this.rowKey] == data[this.rowKey]);
      this.newTableList.splice(index, 1);
    }
    ,

    /**
     * 构建参数请求对象，将请求数组参数转换为参数对象，用于封装请求instanceUForm参数对象
     */
    buildQueryObj(requestForm) {
      let objRequest = {};
      if (requestForm && requestForm.length > 0) {
        requestForm.forEach(val => {
          objRequest[val.label] = val.value
        })
      }
      return objRequest
    }
    ,

    /**
     * 分页查询
     * @param val
     */
    pageChange(val) {
      this.pageBar.pageNum = val.pageNum;
      this.pageBar.pageSize = val.pageSize;
      this.getInit();
    }
    ,
    /**
     * 查询区域，查询点击事件
     */
    queryList(val) {
      this.queryBar.queryData = val;
      this.pageBar.pageNum = 1;
      this.getInit();
    }
    ,
//点击单元格事件，用于可视化界面配置自定义事件调度使用
    cellClick(row, column, cell, event) {
      event.stopPropagation();
      this.currentRow = row;
      this.executeEvent("cellClick", this.path, row, column, cell, event);
    }
    ,
    /**
     * 行点击事件
     */
    rowClick(row, column, event) {
      event.stopPropagation();
      this.currentRow = row;
      this.executeEvent("rowClick", this.path, row, column, event);
    }
    ,

// 删除$字段
    remove$Field(obj) {
      if (obj) {
        for (let key in obj) {
          if (key.indexOf("$") != -1) {
            delete obj[key]
          }
        }
        delete obj['path'];
      }
    }
    ,
    /**
     * 懒加载对应的函数处理接口，用于自定义事件配置时调度使用
     * @param loadParam
     */
    loadMethod(row, treeNode, resolve) {
      this.executeEvent("loadMethod", this.path, row, treeNode, resolve);
    }
    ,
    /**
     *
     * @param {展开的行} row
     * @param {展开状态} expand
     */
    expandChange(row, expand) {
      this.executeEvent("expandChange", this.path, row, expand, this);
    }
    ,
    /**
     * 表格选中行事件
     * @param tableLists
     */
    tableSelected(tableLists) {
      this.multipleSelection = tableLists;
      this.$emit('queryTableListChange', tableLists)
      this.executeEvent("tableSelected", this.path, tableLists);
    }
    ,

//展开或收起表格主体
    expandOrFoldMain() {
      this.tableVisible = !this.tableVisible;
      if (this.tableVisible) {
        this.tableTitle.icon = 'el-icon-arrow-down'
      } else {
        this.tableTitle.icon = 'el-icon-arrow-right'
      }
    }
    ,

//连接websocket
    wsSubscribe(that) {
      //发起topic主题订阅
      if(that.$ws){
        let ws = that.$ws.getWs(that.dataRefresh.connectName);
        if (!ws) {
          console.log("ws未连接");
        } else {
          let data = {
            dieStatus: (nodes) => {
              //存储当前node结果
              that.open(nodes);
              // that.getInit();
            },
          }
          ws.subscribeToModel(that.dataRefresh.topicName, data, {});
        }
      }

    }
  },
  beforeDestroy() {
    let container = document.getElementById(this.canvasId);
  }
}
</script>
<style lang="less" scoped>

</style>
